_G.require("lib.win.user32");
_G.require("lib.win.gdi32");
_G.require("lib.web.ewe");
_G.require("lib.win.kernel32");
namespace win {
    export class form {
        private _hwnd;
        private opt: formOpt;
        private owner: form;
        private wndProcTab = {};
        private m_hWebkit;
        constructor(opt?: formOpt) {
            opt = opt || {} as formOpt;
            opt.caption = opt.caption || "hello";
            opt.hight = opt.hight || WS_CONST.CW_USEDEFAULT;
            opt.width = opt.width || WS_CONST.CW_USEDEFAULT;
            opt.x = opt.x || WS_CONST.CW_USEDEFAULT;
            opt.y = opt.y || WS_CONST.CW_USEDEFAULT;
            opt.className = opt.className || "tsluaWindow";
            opt.style = opt.style || WS_CONST.WS_OVERLAPPEDWINDOW | WS_CONST.WS_VISIBLE;
            this.opt = opt;
            let wc = ffi.new("WNDCLASSA[1]");
            let wndclass = wc[0];
            let hInstance = win.kernel32.GetModuleHandleA(ffi.cast("LPCSTR", 0));
            wndclass.style = CS_CONST.CS_HREDRAW | CS_CONST.CS_VREDRAW;
            let wndProcTab = this.wndProcTab;
            // web.layout.HTMLayoutProcND(0, WM_CONST.WM_CREATE, 0, 0);
            wndclass.lpfnWndProc = function (this: void, hwnd, message, wParam, lParam) {
                //web.layout.HTMLayoutProcND(hwnd, message, wParam, lParam);
                let wndfunc: any[] = wndProcTab[message];
                if (wndfunc) {
                    let rs;
                    for (const iterator of wndfunc) {
                        let f: (this: void, hwnd, message, wParam, lParam) => any = iterator;
                        let r = f && f(hwnd, message, wParam, lParam);
                        rs = rs || r;
                    }
                    if (rs != undefined) return rs;
                }
                return win.user32.defWindowProcA(hwnd, message, wParam, lParam)
            };
            //wndclass.cbClsExtra = 0;
            //wndclass.cbWndExtra = 0;
            //wndclass.hIcon = null;
            //wndclass.hCursor = null;
            //wndclass.lpszMenuName = null;
            //wndclass.hbrBackground = ffi.cast("HBRUSH", gdi32.getStockObject(gdi32.CONST.WHITE_BRUSH));
            wndclass.hInstance = hInstance;
            wndclass.lpszClassName = opt.className;
            win.user32.registerClassA(wc);
            this._hwnd = win.user32.createWindowExA(
                0,
                opt.className,
                opt.caption,
                opt.style,
                opt.x,
                opt.y,
                opt.width,
                opt.hight,
                0,
                ffi.cast("HMENU", 0),
                hInstance,
                ffi.cast("LPVOID", 0)
            )


            let webhwnd = web.ewe.wkeCreateWindow(this.hwnd);
            let eweWindow = web.ewe.wkeGetFromWindow(webhwnd);
            this.m_hWebkit = web.ewe.wkeGetWebView(eweWindow);
            let hosthwnd = web.ewe.wkeGetHostWindow(eweWindow);

            win.user32.showWindow(hosthwnd, SW_CONST.SW_NORMAL);
            win.user32.moveWindow(hosthwnd, 0, 0, opt.width, opt.hight, false);

            win.user32.updateWindow(this.hwnd);
            this.wndProc = {
                [WM_CONST.WM_DESTROY]: () => {
                    win.user32.postQuitMessage(0);
                    return 0;
                },
                [WM_CONST.WM_SIZE]: () => {
                    let rect = win.user32.getWindowRect(this.hwnd);
                    let height = rect.bottom - rect.top;
                    let width = rect.right - rect.left;
                    win.user32.moveWindow(hosthwnd, 0, 0, width, height, false);
                }
            }

        }
        set wndProc(tab: { [k: number]: (hwnd, message, wParam, lParam) => any }) {
            for (const key in tab) {
                let t: any[] = this.wndProcTab[key] = this.wndProcTab[key] || [];
                t.push(tab[key]);
            }
        }
        /**
         * 显示窗口
         * @param sw sw常量,默认为SW_SHOWNORMAL
         */
        show(sw: SW_CONST = SW_CONST.SW_SHOWNORMAL) {
            win.user32.showWindow(this.hwnd, sw);
        }

        set html(html:string) {
            //web.layout.HTMLayoutLoadHtmlEx(this._hwnd, html, html.length, "");
            web.ewe.wkeLoadHTML(this.m_hWebkit, web.ewe.utf8StringToWkeChar(html));
        }
        /**获取整数型窗口句柄 */
        get hwnd() {
            return this._hwnd//ffi.cast("int", this._hwnd);
        }
    }

    export function loopMsg() {
        let msg = ffi.new("MSG[1]");
        while (win.user32.getMessageA(msg, 0, 0, 0) > 0) {
            win.user32.translateMessage(msg);
            win.user32.dispatchMessageA(msg);
        }
    }
    type formOpt = {
        caption?: string
        width?: number
        hight?: number
        style?: WS_CONST
        className?: string
        x?: number,
        y?: number
    }

}



